home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / diskutil / noahdi.zoo / noahdi / hd_low.c < prev    next >
C/C++ Source or Header  |  1992-05-24  |  11KB  |  313 lines

  1. /*
  2.     File: HD_LOW.C       Low Level Harddisk Driver. AHDI Compatible.
  3. */
  4. /*
  5. Copyright (c) 1988 - 1991 by Ted Schipper.
  6.  
  7. Permission to use, copy, modify, and distribute this software and its
  8. documentation for any purpose and without fee is hereby granted,
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in
  11. supporting documentation.
  12.  
  13. This software is provided AS IS with no warranties of any kind.  The author
  14. shall have no liability with respect to the infringement of copyrights,
  15. trade secrets or any patents by this file or any part thereof.  In no
  16. event will the author be liable for any lost revenue or profits or
  17. other special, indirect and consequential damages.
  18. */
  19.  
  20. #include "dma.h"
  21. #include "mfp.h"
  22. #include "hddriver.h"
  23. #include "system.h"
  24.  
  25. /***************************************************************************
  26.  
  27.                             LOW-LEVEL Driver
  28.                            ------------------
  29.  HISTORY
  30. ---------
  31.  Oct 1988. THS. Started. Tested read, write and timeout routines.
  32.                 V0.00
  33.  
  34. ***************************************************************************/
  35.  
  36. /***************************************************************************
  37.  *
  38.  * Function name : hwrite. Write to physical sectors on hard disk.
  39.  * Parameters    : long  sector number. 21 bits address.
  40.  *                 short sector count.   8 bits count.
  41.  *                 long  buffer addr    32 bits address.
  42.  *                 short device number.  4 bits: bit 0   = drive # ( 0 or 1)
  43.  *                                               bit 1-3 = controller # (0-7)
  44.  * Returns       : long OK    = write went ok.
  45.  *                      ERROR = timeout.
  46.  * Description   : Write count sectors to ASCI device, starting at given
  47.  *                 sector number, under DMA. Use the data starting at addr.
  48.  * Comments      : Assumes processor is in supervisor mode, and not more
  49.  *                 than 254 sectors written.
  50.  */
  51.  
  52. long hwrite(sect_nr,sect_cnt,buf_addr,dev)
  53.  
  54.  long  sect_nr;
  55.  short sect_cnt;
  56.  long  buf_addr;
  57.  short dev;
  58.  
  59. {
  60.  long  status;
  61.  short dummy = 0;
  62.  
  63.  FLOCK = -1;                            /* disable FDC operations */
  64.  setdma(buf_addr);                      /* setup DMA transfer address */
  65.  DMA->MODE = NO_DMA | HDC;              /* write 1st byte (0) with A1 low */
  66.  DMA->DATA = (short)((dev >> 1) << 5) | (HD_WRITE); /* cntrl + opcode */
  67.  DMA->MODE = NO_DMA | HDC | A0;         /* A1 high again */
  68.  if (setss(dev,sect_nr,sect_cnt) != OK) /* write bytes 1,2,3,4 to contrlr */
  69.  {
  70.     hdone();                            /* restore DMA device to normal */
  71.     return(ERROR);
  72.  }
  73.  DMA->MODE = NO_DMA | SC_REG;           /* clear FIFO = toggle R/W bit */
  74.  DMA->MODE = DMA_WR | NO_DMA | SC_REG;  /* and select sector count reg */
  75.  DMA->SECT_CNT = sect_cnt;              /* write sector cnt to DMA device */
  76.  DMA->MODE = DMA_WR | NO_DMA | HDC | A0;/* select DMA data register again */
  77.  DMA->DATA = dummy;                     /* write control byte ( = 0 ) */
  78.  DMA->MODE = DMA_WR;                    /* start DMA transfer */
  79.  status = endcmd(DMA_WR | NO_DMA | HDC | A0); /* wait for DMA completion */
  80.  hdone();                               /* restore DMA device to normal */
  81.  return(status);
  82. }
  83.  
  84.  
  85. /***************************************************************************
  86.  *
  87.  * Function name : hread. Read physical sectors from hard disk.
  88.  * Parameters    : long  sector number. 21 bits address.
  89.  *                 short sector count.   8 bits count.
  90.  *                 long  buffer addr    32 bits address.
  91.  *                 short device number.  4 bits: bit 0   = drive # ( 0 or 1)
  92.  *                                               bit 1-3 = controller # (0-7)
  93.  * Returns       : long OK    = read went ok.
  94.  *                      ERROR = timeout.
  95.  * Description   : Read count sectors from ASCI device, starting at given
  96.  *                 sector number, under DMA. Place the data starting at addr.
  97.  *                 
  98.  * Comments      : Assumes processor is in supervisor mode, and not more
  99.  *                 than 254 sectors are read.
  100.  */
  101.  
  102. long hread(sect_nr,sect_cnt,buf_addr,dev)
  103.  
  104.  long  sect_nr;
  105.  short sect_cnt;
  106.  long  buf_addr;
  107.  short dev;
  108.  
  109. {
  110.  long  status;
  111.  short dummy = 0;
  112.  
  113.  FLOCK = -1;                            /* disable FDC operations */
  114.  DMA->MODE = NO_DMA | HDC;              /* write 1st byte (0) with A1 low */
  115.  DMA->DATA = (short)((dev >> 1) << 5) | (HD_READ);
  116.  setdma(buf_addr);                      /* setup DMA transfer address */
  117.  if (setss(dev,sect_nr,sect_cnt) != OK) /* write bytes 1,2,3,4 to contrlr */
  118.  {
  119.     hdone();                            /* restore DMA device to normal */
  120.     return(ERROR);
  121.  }
  122.  DMA->MODE = DMA_WR | NO_DMA | SC_REG;  /* clear FIFO = toggle R/W bit */
  123.  DMA->MODE = NO_DMA | SC_REG;           /* and select sector count reg */
  124.  DMA->SECT_CNT = sect_cnt;              /* write sector cnt to DMA device */
  125.  DMA->MODE = NO_DMA | HDC | A0;         /* select DMA data register again */
  126.  DMA->DATA = dummy;                     /* write control byte ( = 0 ) */
  127.  DMA->MODE = dummy;                     /* start DMA transfer ( = 0 ) */
  128.  status = endcmd(NO_DMA | HDC | A0);    /* wait for DMA completion */
  129.  hdone();                               /* restore DMA device to normal */
  130.  return(status);
  131. }
  132.  
  133.  
  134. /***************************************************************************
  135.  *
  136.  * Function name : endcmd. Wait for end of ASCI command and get status.
  137.  * Parameters    : short Mode word to write DMA mode register.
  138.  * Returns       : long. ASCI completion status or
  139.  *                       ERROR when timeout occured.
  140.  * Description   : Wait for the end of an ASCI command with a long
  141.  *                 timeout. Write mode word to DMA mode register and
  142.  *                 read the DMA data register. Data register should
  143.  *                 contain the completion status byte.
  144.  * Comments      : Assumes processor is in supervisor mode.
  145.  */
  146.  
  147. long endcmd(mode)
  148.  
  149.  short mode;
  150.  
  151. {
  152.  if (fdone() != OK)                   /* wait for operation done ack */
  153.     return(ERRORL);
  154.  DMA->MODE = mode;                    /* write mode word to mode register */
  155.  return((long)(DMA->DATA & 0x00FF));  /* return completion byte */
  156. }
  157.  
  158.  
  159. /***************************************************************************
  160.  *
  161.  * Function name : setss. Set ACSI drive, sector number and number of sectors
  162.  * Parameters    : short drive number. Disk drive number to use.
  163.  *                 long  sector number. First sector to be transfered.
  164.  *                 short sector count.  Number of sectors to be transfered.
  165.  * Returns       : long. OK    = SCSI bytes ack OK.
  166.  *                       ERROR = SCSI bytes not ack, timed out. 
  167.  * Description   : Send 4 bytes: drv | MSB sector, MidSB sector, LSB sector,
  168.  *                 sector count to controller. Wait after each byte for 
  169.  *                 ACSI acknowledge.
  170.  * Comments      : Assumes processor is in supervisor mode.
  171.  */
  172.  
  173. long setss(drv,sect_nr,sect_cnt)
  174.  
  175.  short drv;
  176.  long  sect_nr;
  177.  short sect_cnt;
  178.  
  179. {
  180.  DMA->MODE = NO_DMA | HDC | A0;          /* A0 line high again */
  181.  if (qdone() != OK)                      /* wait for ack */
  182.     return(ERROR);
  183.  
  184.  DMA->DATA = (short)(((drv & 1) << 5) | (((short)(sect_nr >> 16)) & 0x1F));
  185.  DMA->MODE = NO_DMA | HDC | A0;         /* write drv | MSB sector */
  186.  if (qdone() != OK)                     /* wait for ack */
  187.     return(ERROR);
  188.  
  189.  DMA->DATA = (short)((short)sect_nr >> 8); /* write MidSB sector */
  190.  DMA->MODE = NO_DMA | HDC | A0;
  191.  if (qdone() != OK)
  192.     return(ERROR);
  193.  
  194.  DMA->DATA = (short) sect_nr;           /* write LSB sector */
  195.  DMA->MODE = NO_DMA | HDC | A0;
  196.  if (qdone() != OK)
  197.     return(ERROR);
  198.  
  199.  DMA->DATA = (short) sect_cnt;          /* write sector count */
  200.  DMA->MODE = NO_DMA | HDC | A0;
  201.  if (qdone() != OK)
  202.     return(ERROR);
  203.  
  204.  return(OK);                            /* everything OK, tell the caller */
  205. }
  206.  
  207.  
  208. /***************************************************************************
  209.  *
  210.  * Function name : hdone. Restore DMA device to normal.
  211.  * Parameters    : None.
  212.  * Returns       : long. Status of DMA status register.
  213.  * Descripti